package cc.cc4414.cc02.system.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.stereotype.Service;

import cc.cc4414.cc02.core.result.ResultEnum;
import cc.cc4414.cc02.core.result.ResultException;
import cc.cc4414.cc02.system.constant.SystemConsts;
import cc.cc4414.cc02.system.entity.Role;
import cc.cc4414.cc02.system.entity.User;
import cc.cc4414.cc02.system.repository.RoleRepository;
import cc.cc4414.cc02.system.repository.UserRepository;
import cc.cc4414.cc02.system.service.UserService;
import lombok.extern.slf4j.Slf4j;

/**
 * @author cc 2018年4月22日
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private RoleRepository roleRepository;

	@Override
	public void save(User user) {
		if (userRepository.findByUsername(user.getUsername()) != null) {
			throw new ResultException(ResultEnum.USER_EXISTED);
		}
		// id设置为空save方法才是新增，否则是修改
		user.setId(null);
		// 新增用户的默认设置
		user.setCreateTime(new Date());
		user.setState(0);
		// 密码加密
		String password = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(user.getPassword());
		user.setPassword(password);
		try {
			userRepository.save(user);
		} catch (Exception e) {
			log.warn("新增用户【{}】失败", user.getUsername());
			throw new ResultException(ResultEnum.USER_SAVE_ERROR);
		}
	}

	@Override
	public User findByUsername(String username) {
		return userRepository.findByUsername(username);
	}

	@Override
	public void updatePassword(Long id, String password) {
		User user = userRepository.findById(id).get();
		user.setUpdateTime(new Date());
		// 密码加密
		String newPassword = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(password);
		user.setPassword(newPassword);
		userRepository.save(user);
	}

	@Override
	public Page<User> findAll(int page, int size) {
		return userRepository.findByState(0, PageRequest.of(page, size));
	}

	@Override
	public void delete(Long userId) {
		Optional<User> optional = userRepository.findById(userId);
		if (!optional.isPresent()) {
			log.warn("id为{}的用户不存在", userId);
			throw new ResultException(ResultEnum.USER_NOT_EXIST);
		}
		User user = optional.get();
		user.setState(1);
		user.setUpdateTime(new Date());
		userRepository.save(user);
		userRepository.deleteUserRoleByUserId(userId);
	}

	@Override
	public void resetPassword(Long userId) {
		Optional<User> optional = userRepository.findById(userId);
		if (!optional.isPresent()) {
			log.warn("id为{}的用户不存在", userId);
			throw new ResultException(ResultEnum.USER_NOT_EXIST);
		}
		User user = optional.get();
		String password = PasswordEncoderFactories.createDelegatingPasswordEncoder()
				.encode(SystemConsts.DEFAULT_PASSWORD);
		user.setPassword(password);
		user.setUpdateTime(new Date());
		userRepository.save(user);
	}

	@Override
	public void update(User user) {
		Optional<User> optional = userRepository.findById(user.getId());
		if (!optional.isPresent()) {
			log.warn("id为{}的用户不存在", user.getId());
			throw new ResultException(ResultEnum.USER_NOT_EXIST);
		}
		User oldUser = optional.get();
		oldUser.setNickname(user.getNickname());
		oldUser.setMobile(user.getMobile());
		oldUser.setEmail(user.getEmail());
		oldUser.setUpdateTime(new Date());
		userRepository.save(oldUser);
	}

	@Override
	public List<Role> findRoleByUserId(Long userId) {
		return roleRepository.findByUserId(userId);
	}

	@Override
	public void updateUserRole(Long userId, Long[] roleIds) {
		if (!userRepository.findById(userId).isPresent()) {
			log.warn("id为{}的用户不存在", userId);
			throw new ResultException(ResultEnum.USER_NOT_EXIST);
		}
		userRepository.deleteUserRoleByUserId(userId);
		if (roleIds == null) {
			return;
		}
		for (Long roleId : roleIds) {
			userRepository.saveUserRoleByUserIdAndRoleId(userId, roleId);
		}
	}
}
